package gui;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;

import javax.swing.JFileChooser;

/**
 * @author Ramy Refky 
 * */
public class SaveDataHandler {

	MainGui mg;
	File saveFile;
	
	/**
	 * Constructor initializes Save handler.
	 * @param MainGui
	 * */
	public SaveDataHandler(MainGui mg){
		this.mg=mg;
		saveFile = null;
	}
	/**
	 * Performs the save operation. A pop-up dialog appears to select a file to save to, and saves
	 * the workArea's data to that file.
	 * */
	public void save(){
		
		JFileChooser jf = new JFileChooser();
		jf.setDialogTitle("Save as...");
		jf.addChoosableFileFilter(new SBFileFilter());
		jf.setVisible(true);
		
		try{
			
			if (jf.showDialog(null,"Save") == JFileChooser.APPROVE_OPTION)
			{
				saveFile = jf.getSelectedFile();
			}
			String path = saveFile.getAbsolutePath();
			if(!path.endsWith(".sb")){
				saveFile = new File(path + ".sb");
			}
		}
		catch (Exception e){}
		
		int idCounter=1;
		for(int i=0;i<mg.getWorkArea().getAddedComponents().size();i++){
			ComponentGraphics cg = mg.getWorkArea().getAddedComponents().get(i);
			//for each component, give pins id's
			for(int j=0;j<cg.getInputPins().size();j++){
				cg.getInputPins().get(j).setID(idCounter);
				idCounter++;
			}
			for(int j=0;j<cg.getOutputPins().size();j++){
				cg.getOutputPins().get(j).setID(idCounter);
				idCounter++;
			}
		}
		try{
			FileWriter fstream = new FileWriter(saveFile);
			BufferedWriter out = new BufferedWriter(fstream);
			while(mg.getActions().getZoomFactor()>1){
				mg.getActions().setZoomFactor(mg.getActions().getZoomFactor()-0.25);
				
				int newWidthAndHeight= (int) (1500*mg.getActions().getZoomFactor());
				
				mg.getWorkArea().setBounds(0,0,newWidthAndHeight,newWidthAndHeight);
				mg.getVScrollBar().refreshBar();
				mg.getHScrollBar().refreshBar();
				for(int i =0;i<mg.getWorkArea().addedComponents.size();i++){
					mg.getWorkArea().addedComponents.get(i).zoomAdjust(mg.getActions().getZoomFactor());
				}
				mg.getWorkArea().adjustSelectionBox();
				for(int i=0;i<mg.getWorkArea().wiringGrid.getWires().size();i++){
					mg.getWorkArea().wiringGrid.getWires().get(i).maintainWire();
				}
				mg.getWorkArea().drawIntersections();
				mg.getWorkArea().drawWireGroupDisplays();
				mg.repaint();
			}
			while(mg.getActions().getZoomFactor()<1){
				mg.getActions().setZoomFactor(mg.getActions().getZoomFactor()+0.25);
			 
				int newWidthAndHeight= (int) (1500*mg.getActions().getZoomFactor());
				
				mg.getWorkArea().setBounds(0,0,newWidthAndHeight,newWidthAndHeight);
				mg.getVScrollBar().refreshBar();
				mg.getHScrollBar().refreshBar();
				for(int i =0;i<mg.getWorkArea().addedComponents.size();i++){
					mg.getWorkArea().addedComponents.get(i).zoomAdjust(mg.getActions().getZoomFactor());
				}
				for(int i=0;i<mg.getWorkArea().wiringGrid.getWires().size();i++){
					mg.getWorkArea().wiringGrid.getWires().get(i).maintainWire();
				}
				mg.getWorkArea().drawIntersections();
				mg.getWorkArea().drawWireGroupDisplays();
				mg.repaint();
			}
			out.write("<ZoomFactor> "+mg.getActions().getZoomFactor()+" </ZoomFactor>");
			out.newLine();
			out.newLine();
			out.write("<ComponentGraphics>");
			out.newLine();
			out.newLine();
			for(int i=0;i<mg.getWorkArea().getAddedComponents().size();i++){
				
				ComponentGraphics cg = mg.getWorkArea().getAddedComponents().get(i);
				
				out.write("<"+cg.getClass().getSimpleName()+">");
				out.newLine();
				out.write("\t<x> "+cg.getX()+" </x>");
				out.newLine();
				out.write("\t<y> "+cg.getY()+" </y>");
				out.newLine();
				out.write("\t<width> "+cg.getWidth()+" </width>");
				out.newLine();
				out.write("\t<height> "+cg.getHeight()+" </height>");
				out.newLine();
				out.write("\t<numberofinputs> "+cg.getNumberOfInputs()+" </numberofinputs>");
				out.newLine();
				out.write("\t<numberofoutputs> "+cg.getNumberOfOutputs()+" </numberofoutputs>");
				out.newLine();
				if(cg.getClass().getSimpleName().equals("CustomComponentGraphics")){
					out.write("\t<title> "+((CustomComponentGraphics) cg).getComponentText()+" </title>");
					out.newLine();
					out.write("\t<clockpin> "+((CustomComponentGraphics) cg).getClockPin()+" </clockpin>");
					out.newLine();
					out.write("\t<showdetails> "+((CustomComponentGraphics) cg).getShowDetailsValue()+" </showdetails>");
					out.newLine();
				}
				if(cg.getClass().getSimpleName().equals("TextComponentGraphics")){
					out.write("\t<title> "+((TextComponentGraphics) cg).getComponentText()+" </title>");
					out.newLine();
				}
				if(cg.getClass().getSimpleName().equals("ModuleComponentGraphics")){
					out.write("\t<file> "+((ModuleComponentGraphics) cg).getFile().getAbsolutePath()+" </file>");
					out.newLine();
					out.write("\t<showdetails> "+((ModuleComponentGraphics) cg).getShowDetailsValue()+" </showdetails>");
					out.newLine();
				}
				if(cg.getClass().getSimpleName().equals("SplitterComponentGraphics")){
					out.write("\t<option> "+((SplitterComponentGraphics) cg).getOption()+" </option>");
					out.newLine();
				}
				if(cg.getClass().getSimpleName().equals("GrouperComponentGraphics")){
					out.write("\t<option> "+((GrouperComponentGraphics) cg).getOption()+" </option>");
					out.newLine();
				}
				out.write("\t<inputpins>");
				out.newLine();
				for(int j=0;j<cg.getInputPins().size();j++){
					out.write("\t\t<pin>");
				 	out.newLine();
				 	ComponentPin pin = cg.getInputPins().get(j);
				 	out.write("\t\t<id> "+pin.getID()+" </id>");
				 	out.newLine();
				 	out.write("\t\t<connections> "+pin.getConnections()+" </connections>");
				 	out.newLine();
				 	out.write("\t\t<grouped> "+pin.isGrouped()+" </grouped>");
				 	out.newLine();
				 	out.write("\t\t</pin>");
				 	out.newLine();
				}
				out.write("\t</inputpins>");
				out.newLine();
				out.write("\t<outputpins>");
				out.newLine();
				for(int j=0;j<cg.getOutputPins().size();j++){
					out.write("\t\t<pin>");
					out.newLine();
					ComponentPin pin = cg.getOutputPins().get(j);
					out.write("\t\t<id> "+pin.getID()+" </id>");
					out.newLine();
					out.write("\t\t<connections> "+pin.getConnections()+" </connections>");
					out.newLine();
					out.write("\t\t<grouped> "+pin.isGrouped()+" </grouped>");
					out.newLine();
					out.write("\t\t</pin>");
					out.newLine();
				}	
				out.write("\t</outputpins>");
				out.newLine();
				out.write("</"+cg.getClass().getSimpleName()+">");
				out.newLine();
			}
			out.newLine();
			out.write("</ComponentGraphics>");
			out.newLine();
			out.newLine();

			out.write("<Wires>");
		  	out.newLine();
		  	out.newLine();
		  	for(int i=0;i<mg.getWorkArea().getWiringGrid().getWires().size();i++){
		  		Wire w = mg.getWorkArea().getWiringGrid().getWires().get(i);
		  		ArrayList<Double> offsets= w.maintainWire();
		  		out.write("\t<wire>");
		  		out.newLine();
		  		out.write("\t\t<firstpin> "+w.getFirstPin().getID()+" </firstpin>");
		  		out.newLine();
		  		out.write("\t\t<secondpin> "+w.getSecondPin().getID()+" </secondpin>");
		  		out.newLine();
			  	out.write("\t\t<numofsegments> "+w.getWireSegments().size()+" </numofsegments>");
			  	out.newLine();
			  	out.write("\t\t<offsets>");
			  	for(int j=0;j<offsets.size();j++){
			  		out.newLine();  
			  		out.write("\t\t\t<offset> "+offsets.get(j)+" </offset>");
			  	}
			  	out.newLine();
			  	out.write("\t\t</offsets>");
			  	out.newLine();
			  	out.write("\t</wire>");
			  	out.newLine();
		  	}
		  	out.newLine();
		  	out.write("</Wires>");
		  
		  	out.close();
		}
		catch (Exception ex){}
	}
}
